<?php
/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of TicketManager
 *
 * @author joona
 */
class Model_TicketManager extends Core_Model{
    private $tickets = array();

    private $insertQuery = 'INSERT INTO Ticket (name, description, reporterId,
        assigneeId, scrumState, productId, sprintId, originalEstimate, remaining,
        ticketColor) VALUES ({name}, {description}, {reporterId},
        {assigneeId}, {scrumState}, {productId}, {sprintId}, {originalEstimate}, {remaining},
        {ticketColor});';

    private $selectQuery = 'SELECT * FROM Ticket WHERE id = {id} LIMIT 1;';
    private $selectLatest = 'SELECT * FROM Ticket WHERE id = LAST_INSERT_ID() LIMIT 1;';
    /**
     * List of DB-rules
     * @var Array
     */
    private $rules = array(
      'id' => array('type' => Core_Database::Type_Int),
      'name' => array('type' => Core_Database::Type_String, 'maxLength' => 120),
      'description' => array('type' => Core_Database::Type_String, 'allowNull' => true),
      'sprint' => array('type' => Core_Database::Type_Int, 'allowNull' => true),
      'sprintId' => array('type' => Core_Database::Type_Int, 'allowNull' => true),
      'product' => array('type' => Core_Database::Type_Int, 'allowNull' => true),
      'productId' => array('type' => Core_Database::Type_Int, 'allowNull' => true),
      'assignee' => array('type' => Core_Database::Type_Int, 'allowNull' => true),
      'assigneeId' => array('type' => Core_Database::Type_Int, 'allowNull' => true),
      'reporterId' => array('type' => Core_Database::Type_Int, 'allowNull' => true),
      'scrumState' => array('type' => Core_Database::Type_Int),
      'originalEstimate' => array('type' => Core_Database::Type_Int, 'allowNull' => true),
      'remaining' => array('type' => Core_Database::Type_Int, 'allowNull' => true),
      'ticketColor' => array('type' => Core_Database::Type_String, 'allowNull' => true,
          'regexp' => '/[0-9A-F]{6}/')
    );
    
    /**
     * Create new ticket to the system
     * @param $ticketInfo Array of ticket settings
     * @return $newTicket New ticket as an array
     * @throws Model_TicketManager_Exception
     */
    public function create($ticketInfo, $reporterId)
    {
        $ticketInfo['reporterId'] = $reporterId;
        $ticketInfo['scrumState'] = self::SCRUM_STATE_BACKLOG;
        $this->prepareInsert($ticketInfo);
        $db = self::getDatabaseHandler();
        $db->prepare($this->insertQuery);
        $db->execute();
        $db->prepare($this->selectLatest);
        $db->execute();
        return array_pop($db->getAllResults());
    }

    private function prepareInsert($ticketInfo)
    {
        $db = self::getDatabaseHandler();
        $db->setRules($this->rules);
        foreach($ticketInfo as $name => $value)
            $db->setParameter($name, $value);
    }

    /**
     * Loads a list of Tickets that match criteria
     * @param INT $scrumState
     * @param INT $sprintId
     * @param INT $productId
     * @param INT $assigneeId
     */
    public function getTicketsWithCriteria($scrumState, $sprintId = null,
            $productId = null, $assigneeId = null)
    {
        $db = self::getDatabaseHandler();
        $query = 'SELECT * FROM Ticket WHERE ';
        $whereArgs = array();
        $whereClause = array();

        $whereArgs[] = 'scrumState';
        if(!is_null($sprintId))
            $whereArgs[] = 'sprintId';
        if(!is_null($productId))
            $whereArgs[] = 'productId';
        if(!is_null($assigneeId))
            $whereArgs[] = 'assigneeId';

        foreach($whereArgs as $criteria)
        {
            $whereClause[] = $criteria.' = {'.$criteria.'}';
            $db->setParameter("$criteria", $$criteria, $this->rules[$criteria]);
        }
        $query .= implode(' AND ', $whereClause);
        $db->prepare($query);
        $db->execute();
        $listOfTickets = $this->getAllResults();
        $this->includeComments($listOfTickets);
        return $listOfTickets;
    }
    
    private function includeComments(&$listOfTickets)
    {
        foreach($listOfTickets as $index => $ticketInfo)
        {
            $listOfTickets[$index]['comments'] = $this->getCommentsForTicket($ticketInfo['id']);
        }
    }


    /**
     * Get list of Comments for ticket
     * @param INT $ticketId
     */
    public function getCommentsForTicket($ticketId)
    {
        $db = self::getDatabaseHandler();
        $db->prepare('SELECT id, userId, timestamp, comment FROM Comment
               WHERE ticketId = {ticketId} ORDER BY timestamp DESC');
        $db->setParameter('ticketId', (INT)$ticketId, $this->rules['id']);
        $db->execute();
        return $this->getAllResults();
    }
}
class Model_TicketManager_Exception extends Core_Exception{}